//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2005
//
// Change type set of map.
//

# include "StdAfx.h"
# include "ChangeTypeSet.h"
# include "UndoRedo.h"
# include "Types.h"

class CChangeTypeSetAction : public CEditAction {
  public:
	CChangeTypeSetAction (const CTypeSet * _pTypeSet) :
		m_pTypeSetNew (_pTypeSet),
		m_pTypeSetOld (NULL)
	{}

	virtual void GetName (string_t & _str) const {_str.append ("change type set");}
	virtual cu_t CanUndo () const {return cuYes;}
	virtual bool Do ();
	virtual void Undo ();
	virtual void Redo () {CChangeTypeSetAction::Do ();}

  private:
	const CTypeSet * const m_pTypeSetNew;
	const CTypeSet * m_pTypeSetOld;
};

bool CChangeTypeSetAction::Do () {
	CCritSec::CLock lock (g_cs);

//	assert (g_map.pTypeSet == & g_tsNull);

	m_pTypeSetOld = g_map.pTypeSet;
	g_map.pTypeSet = m_pTypeSetNew;

	return true;
}

void CChangeTypeSetAction::Undo () {
	g_map.pTypeSet = m_pTypeSetOld;
}

////////////////////////////////////

class CChangeTypeSetDeepAction : public CEditAction {
  public:
	CChangeTypeSetDeepAction (const CTypeSet * _pTypeSet) :
		m_pTypeSetNew (_pTypeSet),
		m_pTypeSetOld (NULL)
	{}

	virtual void GetName (string_t & _str) const {_str.append ("change type set");}
	virtual cu_t CanUndo () const {return cuBackup;}
	virtual bool Do ();
	virtual void Undo () {}
	virtual void Redo () {}

  private:
	const CTypeSet * const m_pTypeSetNew;
	const CTypeSet * m_pTypeSetOld;
};

bool CChangeTypeSetDeepAction::Do () {
	CCritSec::CLock lock (g_cs);

	m_pTypeSetOld = g_map.pTypeSet;
	g_map.pTypeSet = m_pTypeSetNew;

	const pfConvertTypeSet_t pfConvertTypeSet = m_pTypeSetOld->FindConvertTypeSetTo (m_pTypeSetNew);

	for (size_t cKind = 0; cKind < rkMax; ++ cKind) {
		rgns_t & rgns = g_map.layers [cKind].rgns;

		for (rgns_t::iterator iRgn = rgns.begin (); iRgn != rgns.end (); ++ iRgn) {
			rgn_t & rgn = * iRgn;
			if (rgn.IsDeleted () || rgn.IsWTR ())
				continue;

			rgn.SetType (
				m_pTypeSetNew,
				pfConvertTypeSet (static_cast<RGN_KIND> (cKind), rgn.ushType),
				cKind
			);
		}
	}

	return true;
}

////////////////////////////////////////

void ChangeTypeSet (const CTypeSet * _pTypeSet, bool _bDeep) {
	assert (_pTypeSet);
	if (_bDeep)
		PerformEditAction (new CChangeTypeSetDeepAction (_pTypeSet));
	else
		PerformEditAction (new CChangeTypeSetAction (_pTypeSet));
}
